#ifndef PP_PARSER_H
#define PP_PARSER_H

#include "pp_token.h"

#include <map>

namespace pp
{
    class ParseHandler
    {
    public:
        virtual void StartElement(const std::string& name, const std::map<std::string, std::string>& attrs) = 0;
        virtual void EndElement(const std::string& name) = 0;
    };
    class Parser
    {
    private:
        typedef void (Parser::*FUNCPARSESTATE)(uint32_t pos, const std::shared_ptr<TokenInfo>& token, const std::vector<std::shared_ptr<TokenInfo> >& tokens);
    private:
        uint32_t m_u32Pos;
        FUNCPARSESTATE m_fnState;               // 状态处理函数
        std::vector<std::string> m_oStructs;    // 结构体
        std::shared_ptr<ParseHandler> m_pParseHandler;          // 回调处理函数
    public:
        Parser();

        void SetHandler(std::shared_ptr<ParseHandler> handler) {m_pParseHandler = handler;}

        // 解析字符串
        void Parse(const std::string& data);
        // 解析文件
        void ParseFile(const std::string& fileName);
    private:
        void Reset(); // 重置数据
        void OnStateInit(uint32_t pos, const std::shared_ptr<TokenInfo>& token, const std::vector<std::shared_ptr<TokenInfo> >& tokens);
        void OnStateStruct(uint32_t pos, const std::shared_ptr<TokenInfo>& token, const std::vector<std::shared_ptr<TokenInfo> >& tokens);
        void OnStatePackage(uint32_t pos, const std::shared_ptr<TokenInfo>& token, const std::vector<std::shared_ptr<TokenInfo> >& tokens);
        void OnStateOption(uint32_t pos, const std::shared_ptr<TokenInfo>& token, const std::vector<std::shared_ptr<TokenInfo> >& tokens);
        void OnStateImport(uint32_t pos, const std::shared_ptr<TokenInfo>& token, const std::vector<std::shared_ptr<TokenInfo> >& tokens);
        void OnStateConst(uint32_t pos, const std::shared_ptr<TokenInfo>& token, const std::vector<std::shared_ptr<TokenInfo> >& tokens);
        void OnStateField(uint32_t pos, const std::shared_ptr<TokenInfo>& token, const std::vector<std::shared_ptr<TokenInfo> >& tokens);
        void OnStateMacro(uint32_t pos, const std::shared_ptr<TokenInfo>& token, const std::vector<std::shared_ptr<TokenInfo> >& tokens);
        void EndElement();
    };
};

#endif
